//
// Created by cube on 2020/9/25.
//

#ifndef COMPILERDOMEA1_CONGESTIONCONTROL_H
#define COMPILERDOMEA1_CONGESTIONCONTROL_H

#include "Window.h"
#include "Bbr/bbr.h"

namespace NetBaseCommon {

    class CongestionControl {
    public:
        CongestionControl(const uint32_t &default_pacing_rate)
                : __default_pacing_rate(default_pacing_rate), __inflight(0), __pacing_rate(0), __nextSendTime(0),
                  __acked(0), __delivered(0), __lost(0) {}

        void service(uint32_t &window,const uint32_t &rtt, const uint64_t &now, bool app_limit = false) {
            if (__acked == 0)return;
            __bbr.bbr_main(__inflight, rtt, __acked, now, __delivered, __lost, app_limit, window, __pacing_rate);
            __delivered = __acked = __lost = 0;
        }

        void addLost(const uint32_t &count) { __lost += count; }

        void recv(const uint32_t &size) {
            __acked++;
            __inflight -= size;
            __delivered += size;
        }

        void send_only(const uint32_t &size, const uint64_t &now) {
            uint32_t rate = __pacing_rate ? __pacing_rate : __default_pacing_rate;
            uint32_t msg_len = (uint64_t) size * USEC_PER_MSEC;
            if (rate)msg_len /= rate;
            __nextSendTime = msg_len + now;
        }

        void send(const uint32_t &size, const uint64_t &now) {
            send_only(size, now);
            __inflight += size;
        }

        const uint32_t &lost() { return __lost; }

        const uint32_t &acked() { return __acked; }

        const uint32_t &inflight() { return __inflight; }

        const uint32_t &delivered() { return __delivered; }

        const uint64_t &nextSendTime() { return __nextSendTime; }

        const uint32_t &pacing_rate() { return __pacing_rate; }

        void clear() { __inflight = __acked = __delivered = __lost = __pacing_rate = __nextSendTime = 0; }

    private:
        BBR::CBbr __bbr;
        uint32_t __inflight;
        uint32_t __delivered;

        uint32_t __acked;
//        uint32_t __rtt;
        uint32_t __lost;

        uint32_t __pacing_rate;
        uint64_t __nextSendTime;

        //option
        const uint32_t &__default_pacing_rate;

    };

}

#endif //COMPILERDOMEA1_CONGESTIONCONTROL_H
